/*
 * @Author: cooper
 * @Date: 2025-03-30 21:35:19
 * @Wechat: cmd_develop
 * @Description: 机械臂驱动
 */
#include "./bsp_arm.h"
#include "string.h" // 用于 memcpy
arm_buffer arm_Buffer;

SemaphoreHandle_t arm_receive_sem; // 串口接受信号量

// MKS接收数据处理任务句柄
TaskHandle_t arm_work_task_handler;

/// @brief arm串口DMA接受
/// @param
void ARM_UART_DMA_RX(void)
{
    dma_init_type dma_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* 使能dma复用功能 */
    dmamux_enable(DMA1, TRUE);
    /* 复位指定的 DMA 通道 */
    dma_reset(DMA1_CHANNEL1);
    /* 默认填充配置 */
    dma_default_para_init(&dma_init_struct);
    /* DMA 传输数据量+传输方向 */
    dma_init_struct.buffer_size = ARM_DATA_SIZE;
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
    /* 外设地址+数据宽度+地址增加模式 */
    dma_init_struct.peripheral_base_addr = (uint32_t)&UART8->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    /* 存储器地址+数据宽度+地址增加模式 */
    dma_init_struct.memory_base_addr = (uint32_t)(&(RX_ARM(0)));
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    /* 优先级+循环模式 */
    dma_init_struct.priority = DMA_PRIORITY_HIGH;
    dma_init_struct.loop_mode_enable = FALSE;
    /* 初始化指定的 DMA 通道 */
    dma_init(DMA1_CHANNEL1, &dma_init_struct);
    /* 初始化dma复用功能 */
    dmamux_init(DMA1MUX_CHANNEL1, DMAMUX_DMAREQ_ID_UART8_RX);
    /* 使能指定通道 */
    dma_channel_enable(DMA1_CHANNEL1, TRUE);
    /* 数据接收区数据清理 */
    RX_ARM_BUFCLEAR();
}

/**
 * @brief  arm串口DMA发送
 * @param  none
 * @retval none
 */
void ARM_UART_DMA_TX(u16 size)
{
    dma_init_type dma_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* 使能dma复用功能 */
    dmamux_enable(DMA1, TRUE);
    /* 复位指定的 DMA 通道 */
    dma_reset(DMA1_CHANNEL1);
    /* 默认填充配置 */
    dma_default_para_init(&dma_init_struct);
    /* DMA 传输数据量+传输方向 */
    dma_init_struct.buffer_size = size;
    dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
    /* 存储器地址+数据宽度+地址增加模式 */
    dma_init_struct.memory_base_addr = (uint32_t)(&(TX_ARM(0)));
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    /* 外设地址+数据宽度+地址增加模式 */
    dma_init_struct.peripheral_base_addr = (uint32_t)&UART8->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    /* 优先级+循环模式 */
    dma_init_struct.priority = DMA_PRIORITY_HIGH;
    dma_init_struct.loop_mode_enable = FALSE;
    /* 使能DMA发送完成中断 */
    dma_interrupt_enable(DMA1_CHANNEL1, DMA_FDT_INT, TRUE);
    nvic_irq_enable(DMA1_Channel1_IRQn, 2, 2);
    /* 初始化指定的 DMA 通道 */
    dma_init(DMA1_CHANNEL1, &dma_init_struct);
    /* 初始化dma复用功能 */
    dmamux_init(DMA1MUX_CHANNEL1, DMAMUX_DMAREQ_ID_UART8_TX);
    /* 使能指定通道 */
    dma_channel_enable(DMA1_CHANNEL1, TRUE);
}

/**
 * @brief  4号RS485——arm初始化
 * @param  none
 * @retval none
 */
void ARM_UART_INIT(void)
{
    gpio_init_type gpio_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_UART8_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
    /* GPIO配置 */
    gpio_default_para_init(&gpio_init_struct);
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOE, &gpio_init_struct);
    /* 复用 */
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE1, GPIO_MUX_8);
    gpio_pin_mux_config(GPIOE, GPIO_PINS_SOURCE0, GPIO_MUX_8);
    /* 串口参数 */
    usart_reset(UART8);
    usart_init(UART8, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
    usart_transmitter_enable(UART8, TRUE);
    usart_receiver_enable(UART8, TRUE);
    /* 中断配置 */
    nvic_irq_enable(UART8_IRQn, 2, 2);
    usart_interrupt_enable(UART8, USART_IDLE_INT, TRUE);
    /* 使用DMA */
    usart_dma_receiver_enable(UART8, TRUE);
    usart_dma_transmitter_enable(UART8, TRUE);
    /* 使能 */
    usart_enable(UART8, TRUE);
    /* DMA接收 */
    ARM_UART_DMA_RX();
}

/**
 * @brief  arm串口3中断处理函数
 * @param  none
 * @retval none
 */
void UART8_IRQHandler(void)
{
    uint32_t ulReturn;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    /*进入临界段*/
    ulReturn = taskENTER_CRITICAL_FROM_ISR();
    if (usart_flag_get(UART8, USART_IDLEF_FLAG) != RESET)
    {
        dma_channel_enable(DMA1_CHANNEL1, FALSE);
        dma_flag_clear(DMA1_FDT1_FLAG);
        // 获取接收总数
        RX_ARM_TOTAL = ARM_DATA_SIZE - dma_data_number_get(DMA1_CHANNEL1);
        xSemaphoreGiveFromISR(arm_receive_sem, &xHigherPriorityTaskWoken);
        // 切换任务
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        usart_flag_clear(UART8, USART_IDLEF_FLAG);
    }
    /* 推出临界段 */
    taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}

/**
 * @brief  arm串口DMA1通道1中断处理函数
 * @param  none
 * @retval none
 */
void DMA1_Channel1_IRQHandler(void)
{
    uint32_t ulReturn;
    /* 进入临界段，临界段可以嵌套 */
    ulReturn = taskENTER_CRITICAL_FROM_ISR();
    if (dma_interrupt_flag_get(DMA1_FDT1_FLAG))
    {
        // DMA接收
        ARM_UART_DMA_RX();
        dma_flag_clear(DMA1_FDT1_FLAG);
    }
    /* 退出临界段 */
    taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}
// u8 paw_catch_flag = 0; // 夹爪是否夹住东西

/*************************************** 4号RS485——arm DMA配置 ***************************************/
/**
 * @brief  arm串口DMA接收
 * @param  none
 * @retval none
 */

// 机械臂任务
void arm_work_task_function(void *parameter)
{

    while (1)
    {

        if (xSemaphoreTake(arm_receive_sem, portMAX_DELAY) == pdTRUE)
        {
            logPrintln("receive");

            for (int i = 0; i <= RX_ARM_TOTAL - 1; i++)
            {
                logPrintln("i:%d:%x\t", i, arm_Buffer.rx_data[i]);
            }
        }
        else
        {
            vTaskDelay(pdMS_TO_TICKS(3000));
        }
    }
}

void ARM_TASK(void)
{
    arm_receive_sem = xSemaphoreCreateBinary();
    // 创建长轴工作任务
    xTaskCreate((TaskFunction_t)arm_work_task_function,
                (const char *)"ARM_WORK_TASK",
                (uint16_t)configMINIMAL_STACK_SIZE * 4, // 128
                (void *)NULL,
                (UBaseType_t)3,
                (TaskHandle_t *)&arm_work_task_handler);
}

void ARM_TASK_DEINIT(void)
{
    if (arm_work_task_handler != NULL)
    {
        vTaskSuspend(arm_work_task_handler);
    }
}

void ARM_SEND(void)
{
    TX_ARM_TOTAL = 5;
    logPrintln(" TX_ARM_TOTAL= %d\n", TX_ARM_TOTAL);
    for (int i = 0; i <= TX_ARM_TOTAL - 1; i++)
    {
        arm_Buffer.tx_data[i] = 30 + i;
    }
    ARM_UART_DMA_TX(TX_ARM_TOTAL);
}
